package com.demo2do.fms.entity.driver;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;

import com.demo2do.core.format.PersistentFormat;
import com.demo2do.fms.entity.authority.Organization;
import com.demo2do.fms.entity.supplier.common.Supplier;

/**
 * 
 * @author mohanlan
 *
 */
@Entity
@Table(name = "FMS_DRIVER")
@DynamicInsert
@DynamicUpdate
@PersistentFormat
public class Driver {
    
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
    @SequenceGenerator(name = "generator", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1)
    private Long id;
    
    /** 所属公司名称 */
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "organization_id", referencedColumnName = "id")
    @PersistentFormat
    private Organization organization;
    
    /** 所属供应商 */
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    @JoinColumn(name = "supplier_id", referencedColumnName = "id")
    private Supplier supplier;

    /** 姓名 */
    private String name;

    /** 工号 */
    @Column(name = "employee_code")
    private String code;
    
    /** 性别 */
    private String gender;

    /** 身份证号 */
    @Column(name = "citizen_code")
    private String citizenCode;

    /** 生日 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;

    /** 职务ID */
    @Column(name = "duty_id")
    private Long dutyId;

    /** 车辆ID */
    private Long vehicleId;
    
    /** 是否有绑定车辆 */
    @Column(name = "is_bind")
    private boolean bind;

    /** 手机号码 */
    private String mp;

    /** 是否激活 */
    @Column(name = "is_active")
    private Boolean active;
    
    /** 是否删除、是否在职 */
    @Column(name = "is_disabled")
    private Boolean disabled;

    /** 教育程度 */
    private Long educationLevel;

    /** 政治面貌 */
    private Long clanId;

    /** 加入时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date joinDate;

    /** 学校 */
    private String school;

    /** 毕业时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date graduateDate;

    /** 专业 */
    private String speciality;

    /** 学位 */
    private Long degreeId;

    /** 家庭住址 */
    private String homeAddress;

    /** 通讯地址 */
    private String contactAddress;

    /** 住址邮政编码 */
    private String homeZipcode;

    /** 通讯地址邮政编码 */
    private String contactZipcode;

    /** 联系人姓名 */
    private String contactorName;

    /** 联系人称谓 */
    private String contactorAppellation;

    /** 电话 */
    private String tel;

    /** 备注 */
    private String description;

    /** 创建时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "CREATE_TIME")
    private Date createDate;

    /** 最后修改时间 */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @Column(name = "LAST_MODIFY_TIME")
    private Date lastModifyDate;

    /** 创建人 */
    private Long creatorId;

    /** 最后操作人 */
    private Long lastOperatorId;

    /** BOARD_DATE */
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date boardDate;

    /** 驾龄 */
    private Long drivingAge;

    /**
     * 劳务合同签署方
     * 
     *      - 01 - 公司
     *      - 02 - 中介
     */
    private String contractParty;

    /**
     * 准驾车型 
     *      
     *      - 01--A1,
     *      - 02--A2,
     *      - 03--B2
     *      - 04--B1
     *      - 05--C1
     */
    private String drivingType;

    /** 身份证正面 */
    private String idFrontPhoto;

    /** 身份证背面 */
    private String idBackPhoto;

    /** 驾照原件 */
    private String license;

    /** 驾照副本扫描件 */
    private String licenseBack;

    /** 第三方验证 */
    private String thirdAuthentication;

    /** 正面免冠照 */
    private String avatar;

    /** 审核状态 */
    @Enumerated(EnumType.STRING)
    private DriverAuditStatus status;
    
    /** 退回意见(备注) */
    private String rejectedReason;
    
    /** 驳回理由 */
    private String reason;
    
    /** 司机管家用户激活状态 */
    @Column(name = "APP_STATE")
    private Boolean appState;
    
    /** 是否是黑名单 */
    @Column(name = "IS_BLACK")
    private Boolean black;
    
    /** 能级得分 */
    private Double score;
    
    /**
     * The default constructor
     */
    public Driver() {
    }
    
    /**
     * 
     * @param supplier
     * @param organization
     * @param name
     * @param gender
     * @param code
     * @param citizenCode
     * @param birthday
     * @param mp
     * @param dutyId
     * @param drivingAge
     * @param contractParty
     * @param drivingType
     * @param now
     * @param operator
     */
    public Driver(Supplier supplier, Organization organization, String name, String gender, String code, String citizenCode,
                  Date birthday, String mp, Long dutyId, Long drivingAge, String contractParty,
                  String drivingType, Date now, Long operator) {

        this.supplier = supplier;
        this.organization = organization;

        this.name = name;
        this.gender = gender;
        this.code = code;
        this.citizenCode = citizenCode;
        this.birthday = birthday;
        this.mp = mp;
        this.dutyId = dutyId;
        this.drivingAge = drivingAge;
        this.contractParty = contractParty;
        this.drivingType = drivingType;

        this.active = false;
        this.appState = false;
        this.disabled = false;
        this.status = DriverAuditStatus.EDITING;

        this.creatorId = operator;
        this.createDate = now;
        this.lastOperatorId = operator;
        this.lastModifyDate = now;
    }
    
    /**
     * 
     * @param supplier
     * @param organizationId
     * @param operator
     * @return
     */
    public Driver initialize(Supplier supplier, Organization organization, Long operator) {
        this.supplier = supplier;
        this.organization = organization;
        this.status = DriverAuditStatus.EDITING;
        this.active = false;
        this.appState = false;
        this.disabled = false;
        this.creatorId = operator;
        this.createDate = new Date();
        this.lastOperatorId = operator;
        this.lastModifyDate = new Date();
        return this;
    }
    
    /**
     * @param driver
     */
    public Driver updateBasic(Driver driver, Long operator, Date lastModifyDate) {
        
        this.lastOperatorId = operator;
        
        this.lastModifyDate = lastModifyDate;
        
        this.name = driver.getName();
        
        this.gender = driver.getGender();
        
        this.citizenCode = driver.getCitizenCode();
        
        this.birthday = driver.getBirthday();
        
        this.mp = driver.getMp();
        
        this.code = driver.getCode();
        
        this.dutyId = driver.getDutyId();
        
        this.drivingAge = driver.getDrivingAge();
        
        this.contractParty = driver.getContractParty();
        
        this.drivingType = driver.getDrivingType();
        
        this.active = driver.getActive();
                
        return this;
    }
    
    /**
     * @param operator
     * @param now
     * @return
     */
    public Driver unbind(Long operator, Date now) {
        this.vehicleId = null;
        this.bind = false;
        this.lastOperatorId = operator;
        this.lastModifyDate = now;
        return this;
    }
    
    /**
     * @param lastModifyDate
     * @param lastOperatorId
     * @return
     */
    public Driver operate(Date lastModifyDate, Long lastOperatorId) {
        this.lastModifyDate = lastModifyDate;
        this.lastOperatorId = lastOperatorId;
        return this;
    }
    
    /**
     * 递交审核
     * 
     * @param operator
     * @return
     */
    public Driver audit(Long operator) {
        this.status = DriverAuditStatus.AUDIT;
        this.lastOperatorId = operator;
        this.lastModifyDate = new Date();
        return this;
    }
    
    /**
     * 通过审核
     * 
     * @param operator
     * @return
     */
    public Driver adopt(Long operator) {
        this.status = DriverAuditStatus.QUALIFIED;
        this.lastOperatorId = operator;
        this.lastModifyDate = new Date();
        return this;
    }
    
    /**
     * 驳回审核
     * 
     * @param operator
     * @return
     */
    public Driver reject(Long operator) {
        this.status = DriverAuditStatus.REJECTED;
        this.lastOperatorId = operator;
        this.lastModifyDate = new Date();
        return this;
    }
    
    /**
     * @param operatorId
     * @return
     */
    public Driver quit(Long operatorId) {
        this.disabled = true;
        this.lastOperatorId = operatorId;
        this.lastModifyDate = new Date();
        return this;
    }

    /**
     * @param vehicleId
     * @return
     */
    public Driver bind(Long vehicleId) {
        this.bind = true;
        this.vehicleId = vehicleId;
        return this;
    }
    
    /**
     * @param id
     * @return
     */
    public Driver editId(Long id) {
    	this.id = id;
    	return this;
    }
    
    /**
     * @param driver
     * @return
     */
    public Driver createQuit(Driver driver) {
    	this.educationLevel = driver.getEducationLevel();
    	this.clanId = driver.getClanId();
    	this.joinDate = driver.getJoinDate();
    	this.school = driver.getSchool();
    	this.speciality = driver.getSpeciality();
    	this.degreeId = driver.getDegreeId();
    	this.graduateDate = driver.getGraduateDate();
    	this.homeAddress = driver.getHomeAddress();
    	this.homeZipcode = driver.getHomeZipcode();
    	this.contactAddress = driver.getContactAddress();
    	this.contactZipcode = driver.getContactZipcode();
    	this.contactorName = driver.getContactorName();
    	this.contactorAppellation = driver.getContactorAppellation();
    	this.tel = driver.getTel();
    	this.description = driver.getDescription();
    	return this;
    }
    
    /**
     * 是否能上传
     * 
     * @return
     */
    public boolean couldUpload() {
        return StringUtils.isNotBlank(code) && 
               StringUtils.isNotBlank(citizenCode) && 
               StringUtils.isNotBlank(name) &&
               StringUtils.isNotBlank(gender) &&
               birthday != null && 
               StringUtils.isNotBlank(mp) &&
               dutyId != null && 
               drivingAge != null &&
               StringUtils.isNotBlank(contractParty) && 
               StringUtils.isNotBlank(drivingType);
    }
    
    /**
     * 
     * @return
     */
    public String couldAudit() {
        
        if (StringUtils.isBlank(name)) {
            return "司机姓名不能为空";
        } else if (StringUtils.isBlank(code)) {
            return "司机工号不能为空";
        } else if (StringUtils.isBlank(gender)) {
            return "司机性别不能为空";
        } else if (StringUtils.isBlank(citizenCode)) {
            return "司机身份证号不能为空";
        } else if (birthday == null) {
            return "司机生日不能为空";
        } else if (dutyId == null) {
            return "司机职务不能为空";
        } else if (StringUtils.isBlank(mp)) {
            return "司机手机号码不能为空";
        } else if (supplier == null) {
            return "司机无所属供应商";
        } else if (StringUtils.isBlank(idFrontPhoto)) {
            return "司机身份证正面照未上传";
        } else if (StringUtils.isBlank(idBackPhoto)) {
            return "司机身份证背面照未上传";
        } else if (StringUtils.isBlank(license)) {
            return "司机驾照原件未上传";
        } else if (StringUtils.isBlank(licenseBack)) {
            return "司机驾照副本扫描件未上传";
        } else if (disabled) {
            return "司机已失效";
        } else {
            return null;
        }
        
    }
    
    /**
     * @param operator
     * @return
     */
    public Driver disable(Long operator) {
        this.disabled = true;
        this.lastOperatorId = operator;
        this.lastModifyDate = new Date();
        return this;
    }
    
    /**
     * @param isBlack
     */
    public Driver updateBlack(Boolean isBlack) {
        
        this.black = isBlack;
        
        return this;
    }
    
    /**
     * @param score
     */
    public Driver updateScore(Double score) {

        this.score = score;
        
        return this;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @return the code
     */
    public String getCode() {
        return code;
    }

    /**
     * @return the gender
     */
    public String getGender() {
        return gender;
    }

    /**
     * @return the citizenCode
     */
    public String getCitizenCode() {
        return citizenCode;
    }

    /**
     * @return the birthday
     */
    public Date getBirthday() {
        return birthday;
    }

    /**
     * @return the dutyId
     */
    public Long getDutyId() {
        return dutyId;
    }

    /**
     * @return the vehicleId
     */
    public Long getVehicleId() {
        return vehicleId;
    }
    
    /**
     * @return
     */
    public boolean isBind() {
        return bind;
    }

    /**
     * @return the mp
     */
    public String getMp() {
        return mp;
    }

    /**
     * @return the organization
     */
    public Organization getOrganization() {
        return organization;
    }
    
    /**
     * @return
     */
    public Supplier getSupplier() {
		return supplier;
	}

    /**
     * @return the active
     */
    public Boolean getActive() {
        return active;
    }

    /**
     * @return the disabled
     */
    public Boolean getDisabled() {
        return disabled;
    }

    /**
     * @return the educationLevel
     */
    public Long getEducationLevel() {
        return educationLevel;
    }

    /**
     * @return the clanId
     */
    public Long getClanId() {
        return clanId;
    }

    /**
     * @return the joinDate
     */
    public Date getJoinDate() {
        return joinDate;
    }

    /**
     * @return the school
     */
    public String getSchool() {
        return school;
    }

    /**
     * @return the graduateDate
     */
    public Date getGraduateDate() {
        return graduateDate;
    }

    /**
     * @return the speciality
     */
    public String getSpeciality() {
        return speciality;
    }

    /**
     * @return the degreeId
     */
    public Long getDegreeId() {
        return degreeId;
    }

    /**
     * @return the homeAddress
     */
    public String getHomeAddress() {
        return homeAddress;
    }

    /**
     * @return the contactAddress
     */
    public String getContactAddress() {
        return contactAddress;
    }

    /**
     * @return the homeZipcode
     */
    public String getHomeZipcode() {
        return homeZipcode;
    }

    /**
     * @return the contactZipcode
     */
    public String getContactZipcode() {
        return contactZipcode;
    }

    /**
     * @return the contactorName
     */
    public String getContactorName() {
        return contactorName;
    }

    /**
     * @return the contactorAppellation
     */
    public String getContactorAppellation() {
        return contactorAppellation;
    }

    /**
     * @return the tel
     */
    public String getTel() {
        return tel;
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @return the createDate
     */
    public Date getCreateDate() {
        return createDate;
    }

    /**
     * @return the lastModifyDate
     */
    public Date getLastModifyDate() {
        return lastModifyDate;
    }

    /**
     * @return the creatorId
     */
    public Long getCreatorId() {
        return creatorId;
    }

    /**
     * @return the lastOperatorId
     */
    public Long getLastOperatorId() {
        return lastOperatorId;
    }

    /**
     * @return the boardDate
     */
    public Date getBoardDate() {
        return boardDate;
    }

    /**
     * @return the drivingAge
     */
    public Long getDrivingAge() {
        return drivingAge;
    }

    /**
     * @return the contractParty
     */
    public String getContractParty() {
        return contractParty;
    }

    /**
     * @return the drivingType
     */
    public String getDrivingType() {
        return drivingType;
    }

    /**
     * @return the idFrontPhoto
     */
    public String getIdFrontPhoto() {
        return idFrontPhoto;
    }

    /**
     * @return the idBackPhoto
     */
    public String getIdBackPhoto() {
        return idBackPhoto;
    }

    /**
     * @return the license
     */
    public String getLicense() {
        return license;
    }

    /**
     * @return the licenseBack
     */
    public String getLicenseBack() {
        return licenseBack;
    }

    /**
     * @return the thirdAuthentication
     */
    public String getThirdAuthentication() {
        return thirdAuthentication;
    }

    /**
     * @return the avatar
     */
    public String getAvatar() {
        return avatar;
    }

    /**
     * @return the status
     */
    public DriverAuditStatus getStatus() {
        return status;
    }

    /**
     * @return the rejectedReason
     */
    public String getRejectedReason() {
        return rejectedReason;
    }

    /**
     * @return the reason
     */
    public String getReason() {
        return reason;
    }
    
    /**
     * @return
     */
    public Boolean getAppState() {
		return appState;
	}

    /**
     * @param id the id to set
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @param code the code to set
     */
    public void setCode(String code) {
        this.code = code;
    }

    /**
     * @param gender the gender to set
     */
    public void setGender(String gender) {
        this.gender = gender;
    }

    /**
     * @param citizenCode the citizenCode to set
     */
    public void setCitizenCode(String citizenCode) {
        this.citizenCode = citizenCode;
    }

    /**
     * @param birthday the birthday to set
     */
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    /**
     * @param dutyId the dutyId to set
     */
    public void setDutyId(Long dutyId) {
        this.dutyId = dutyId;
    }

    /**
     * @param vehicleId the vehicleId to set
     */
    public void setVehicleId(Long vehicleId) {
        this.vehicleId = vehicleId;
    }

    /**
     * @param mp the mp to set
     */
    public void setMp(String mp) {
        this.mp = mp;
    }

    /**
     * @param organization the organization to set
     */
    public void setOrganization(Organization organization) {
        this.organization = organization;
    }
    
    /**
     * @param supplier
     */
    public void setSupplier(Supplier supplier) {
		this.supplier = supplier;
	}

    /**
     * @param active the active to set
     */
    public void setActive(Boolean active) {
        this.active = active;
    }

    /**
     * @param disabled the disabled to set
     */
    public void setDisabled(Boolean disabled) {
        this.disabled = disabled;
    }

    /**
     * @param educationLevel the educationLevel to set
     */
    public void setEducationLevel(Long educationLevel) {
        this.educationLevel = educationLevel;
    }

    /**
     * @param clanId the clanId to set
     */
    public void setClanId(Long clanId) {
        this.clanId = clanId;
    }

    /**
     * @param joinDate the joinDate to set
     */
    public void setJoinDate(Date joinDate) {
        this.joinDate = joinDate;
    }

    /**
     * @param school the school to set
     */
    public void setSchool(String school) {
        this.school = school;
    }

    /**
     * @param graduateDate the graduateDate to set
     */
    public void setGraduateDate(Date graduateDate) {
        this.graduateDate = graduateDate;
    }

    /**
     * @param speciality the speciality to set
     */
    public void setSpeciality(String speciality) {
        this.speciality = speciality;
    }

    /**
     * @param degreeId the degreeId to set
     */
    public void setDegreeId(Long degreeId) {
        this.degreeId = degreeId;
    }

    /**
     * @param homeAddress the homeAddress to set
     */
    public void setHomeAddress(String homeAddress) {
        this.homeAddress = homeAddress;
    }

    /**
     * @param contactAddress the contactAddress to set
     */
    public void setContactAddress(String contactAddress) {
        this.contactAddress = contactAddress;
    }

    /**
     * @param homeZipcode the homeZipcode to set
     */
    public void setHomeZipcode(String homeZipcode) {
        this.homeZipcode = homeZipcode;
    }

    /**
     * @param contactZipcode the contactZipcode to set
     */
    public void setContactZipcode(String contactZipcode) {
        this.contactZipcode = contactZipcode;
    }

    /**
     * @param contactorName the contactorName to set
     */
    public void setContactorName(String contactorName) {
        this.contactorName = contactorName;
    }

    /**
     * @param contactorAppellation the contactorAppellation to set
     */
    public void setContactorAppellation(String contactorAppellation) {
        this.contactorAppellation = contactorAppellation;
    }

    /**
     * @param tel the tel to set
     */
    public void setTel(String tel) {
        this.tel = tel;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * @param createDate the createDate to set
     */
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    /**
     * @param lastModifyDate the lastModifyDate to set
     */
    public void setLastModifyDate(Date lastModifyDate) {
        this.lastModifyDate = lastModifyDate;
    }

    /**
     * @param creatorId the creatorId to set
     */
    public void setCreatorId(Long creatorId) {
        this.creatorId = creatorId;
    }

    /**
     * @param lastOperatorId the lastOperatorId to set
     */
    public void setLastOperatorId(Long lastOperatorId) {
        this.lastOperatorId = lastOperatorId;
    }

    /**
     * @param boardDate the boardDate to set
     */
    public void setBoardDate(Date boardDate) {
        this.boardDate = boardDate;
    }

    /**
     * @param drivingAge the drivingAge to set
     */
    public void setDrivingAge(Long drivingAge) {
        this.drivingAge = drivingAge;
    }

    /**
     * @param contractParty the contractParty to set
     */
    public void setContractParty(String contractParty) {
        this.contractParty = contractParty;
    }

    /**
     * @param drivingType the drivingType to set
     */
    public void setDrivingType(String drivingType) {
        this.drivingType = drivingType;
    }

    /**
     * @param idFrontPhoto the idFrontPhoto to set
     */
    public void setIdFrontPhoto(String idFrontPhoto) {
        this.idFrontPhoto = idFrontPhoto;
    }

    /**
     * @param idBackPhoto the idBackPhoto to set
     */
    public void setIdBackPhoto(String idBackPhoto) {
        this.idBackPhoto = idBackPhoto;
    }

    /**
     * @param license the license to set
     */
    public void setLicense(String license) {
        this.license = license;
    }

    /**
     * @param licenseBack the licenseBack to set
     */
    public void setLicenseBack(String licenseBack) {
        this.licenseBack = licenseBack;
    }

    /**
     * @param thirdAuthentication the thirdAuthentication to set
     */
    public void setThirdAuthentication(String thirdAuthentication) {
        this.thirdAuthentication = thirdAuthentication;
    }

    /**
     * @param avatar the avatar to set
     */
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(DriverAuditStatus status) {
        this.status = status;
    }

    /**
     * @param rejectedReason the rejectedReason to set
     */
    public void setRejectedReason(String rejectedReason) {
        this.rejectedReason = rejectedReason;
    }

    /**
     * @param reason the reason to set
     */
    public void setReason(String reason) {
        this.reason = reason;
    }
    
    /**
     * @param appState
     */
    public void setAppState(Boolean appState) {
		this.appState = appState;
	}

    /**
     * @return the black
     */
    public Boolean getBlack() {
        return black;
    }

    /**
     * @param black the black to set
     */
    public void setBlack(Boolean black) {
        this.black = black;
    }

    /**
     * @return the score
     */
    public Double getScore() {
        return score;
    }

    /**
     * @param score the score to set
     */
    public void setScore(Double score) {
        this.score = score;
    }

}
